import src from './source';
import * as _ from './common';
import WfForm_Public from './interface';
import { verifyCustomRegisterEvent } from './globalUtil';
const jQuery = window.jQuery;

//获取明细对象
export const getDetailObj = (detailMark) =>{
    const { detailMap } = src.layoutStore;
    if(!detailMap.has(detailMark)){
        /* eslint no-console: 0 */
        if(window.console)  console.error(`getDetailObj ${detailMark} Not Exist`);
        return null;
    }
    return detailMap.get(detailMark);
}

//判定移动端明细是否卡片编辑
export const judgeIsCardEdit = (detailObj) =>{
    return !(detailObj && detailObj.attr && detailObj.attr.mobilecardedit === 0);
}

//获取选中行数组
export const getDetailCheckedRowArr = (detailObj) =>{
    let rowArr = [];
    detailObj.rowInfo.forEach((info,rowKey) =>{
        if(info.get("checked"))
            rowArr.push(rowKey.substring(4));
    });
    return rowArr;
}

//选中单行
export const setRowChecked = (detailMark, rowIndex, bool) =>{
    const detailObj = getDetailObj(detailMark);
    detailObj && detailObj.controlRowChecked(rowIndex.toString(), bool);
}

//全部选中
export const setAllRowChecked = (detailMark, bool) =>{
    const detailObj = getDetailObj(detailMark);
    detailObj && detailObj.controlRowChecked(detailObj.currentPageRowIndexStr, bool);
}

//新增明细行(统一调用此方法)
export const addRow = (detailMark, initAddRowData={}, fromLinkage=false, isCopy=false) =>{
    const detailObj = getDetailObj(detailMark);
    if(detailObj === null)
        return;
    const detailIndex = parseInt(detailMark.substring(7));
    return verifyCustomRegisterEvent(WfForm_Public.OPER_ADDROW+detailIndex, ()=>{
        const addRowIndex = parseInt(detailObj.indexnum);   //新增前取
        detailObj.add_Row(initAddRowData, fromLinkage, isCopy);
        src.layoutStore.triggerAllLinkage(3, detailMark, "", addRowIndex);
        //执行自定义新增行接口，延时解决DOM先变更，函数体取新增行值情况
        WfForm_Public.triggerAction(WfForm_Public.ACTION_ADDROW+detailIndex, [addRowIndex], 100);
        window.setTimeout(function(){
            syncFixedHeadWidth(detailIndex-1);    //需要延时，解决只读情况添加行为可编辑行又自撑问题
        }, 50);
        return addRowIndex;
    });
}

//复制明细行
export const copyDetailRow = (detailMark) => {
    const detailObj = getDetailObj(detailMark);
    if (detailObj === null)
        return;
    const rowArr = getDetailCheckedRowArr(detailObj);
    if (rowArr.length === 0)
        return;
    copyRow(detailMark, rowArr);
}

//复制明细行(统一调用此方法)
export const copyRow = (detailMark, rowArr=[]) =>{
    const detailObj = getDetailObj(detailMark);
    if(rowArr.length === 0 || detailObj === null)
        return;
    rowArr.sort((a,b) =>{
        return a - b;
    });
    const { rowInfo,fieldInfo,detailData } = detailObj;
    rowArr.map(destRow =>{
        if(parseInt(destRow) < 0 || !rowInfo.has(`row_${destRow}`))
            return true;
        let initData = {};
        _.forIn(fieldInfo, (v,k)=>{
            if(detailData.has(`field${k}_${destRow}`) && v.htmltype !== 6)
                initData[`field${k}`] = detailData.get(`field${k}_${destRow}`).valueObj;
        });
        addRow(detailMark, initData, false, true);
    });
    // detailObj.clearAllRowChecked();
}

//删除明细指定行(统一调用此方法)
export const delAssignRow = (detailMark, rowArr) =>{
    const detailObj = getDetailObj(detailMark);
    if(detailObj === null)
        return;
    const detailIndex = parseInt(detailMark.substring(7));
    return verifyCustomRegisterEvent(WfForm_Public.OPER_DELROW+detailIndex, ()=>{
        detailObj.del_Row(rowArr);
        src.layoutStore.triggerAllLinkage(4, detailMark, '', rowArr.join(","));
        //执行自定义删除行接口
        WfForm_Public.triggerAction(WfForm_Public.ACTION_DELROW+detailIndex, [rowArr], 50);
    });
}

//判断明细是否含有合计字段(用于低级模式是否需要扩充合计行)
export const judgeDetailContainSum = (detailMark) =>{
    let containSum = false;
    const { detailMap,cellInfo,linkageCfg } = src.layoutStore;
    const detailObj = detailMap.get(detailMark);
    _.forIn(detailObj.fieldInfo, (v,fieldid) =>{
        if(v.viewattr > 0 && _.has(cellInfo, ["fieldCellInfo", fieldid]) && _.has(linkageCfg, ["colCalCfg", fieldid])){
            containSum = true;
            return false;
        }
    });
    return containSum;
}

//滚动过程中控制表头固定
export const fixedDetailHead = () =>{
    const container = src.isMobile ? jQuery('.wf-req-content') : jQuery('.wf-req-form-scroll');
    const conOffsetTop = container.offset().top;
    container.find(".excelDetailTableDiv").each(function(){
        const groupid = jQuery(this).attr("data-groupid");
        const detailFixedDiv = jQuery(this).find("[class^=excelDetailFixedHead]");
        const detailTable = jQuery("#oTable"+groupid);
        const lockedBtn = jQuery(this).parent().find(".wf-detail-locked-btnrow");
        const existLockedBtn = lockedBtn.length > 0;
        let detailHeight = detailTable.height();
        const unFixedFn = () =>{
            if(existLockedBtn)
                lockedBtn.removeClass("wf-detail-locked-btnrow-fixed");
            detailFixedDiv.hide();
        }
        if(detailHeight < 300){     //此if不能后移，会导致部分ios滑动闪屏，why...
            unFixedFn();
            return true;
        }
        let detailOffsetTop = detailTable.offset().top;
        let fixedHeadHeight = detailFixedDiv.height();
        let lockedBtnHeight = 0;
        if(existLockedBtn){
            lockedBtnHeight = lockedBtn.height();
            detailHeight += lockedBtnHeight;
            fixedHeadHeight += lockedBtnHeight;
        }
        const fixedFn = () =>{
            if(existLockedBtn){
                lockedBtn.addClass("wf-detail-locked-btnrow-fixed");
                lockedBtn.find(".wf-detail-locked-btnrow-content").css("top", conOffsetTop);
            }
            detailFixedDiv.css("top", conOffsetTop+lockedBtnHeight).show();
            syncFixedHeadWidth(groupid);
            syncDetailScrollXPosition(groupid);
        }
        //冻结表头，明细表最低要求200px高度
        //console.log("groupid",groupid,"detailHeight",detailHeight,"detailOffsetTop",detailOffsetTop,"conOffsetTop",conOffsetTop,"fixedHeadHeight",fixedHeadHeight);
        if(detailOffsetTop < conOffsetTop && detailOffsetTop + detailHeight >= fixedHeadHeight + conOffsetTop){
            fixedFn();
        }else{
            unFixedFn();
        }
    });
}

//同步列宽到固定表头,列锁定情况仅同步滚动区域
export const syncFixedHeadWidth = (groupid) => {
    try{
        const detailTable = jQuery("#oTable"+groupid);
        const detailFixedTable = jQuery("#oTable"+groupid+"_head");
        const detailFixedDiv = detailFixedTable.parent();
        if(!detailFixedDiv.is(":hidden")){
            detailFixedTable.width(detailTable.width());
            const fixedWidthRow = detailFixedTable.find("tr.detailControlWidth");
            detailTable.find("tr.detailControlWidth").children().each(function(index){
                fixedWidthRow.find("td:eq("+index+")").css("width", jQuery(this).width()+"px");
            });
            detailFixedDiv.css("width", detailFixedDiv.parent().width());
        }
    }catch(e){}
}

//同步横向滚动条位置到固定表头
export const syncDetailScrollXPosition = (groupid) => {
    try{
        const detailArea = window.jQuery("#dTableArea_"+groupid);
        detailArea.find(".excelDetailFixedHead").scrollLeft(detailArea.find(".excelDetailContent").scrollLeft());
    }catch(e){}
}

//锁定列情况，加载完同步一次高度宽度
export const syncLockedForDidMount = (groupid) => {
    const syncFn = () =>{
        const dTableArea = jQuery("#dTableArea_"+groupid);
        if(dTableArea.attr("data-supportlockedcol") !== "true")
            return;
        const oTable = dTableArea.find("table#oTable"+groupid);
        const oTable_head = dTableArea.find("table#oTable"+groupid+"_head");
        const oTableLocked = dTableArea.find("table#oTable"+groupid+"_locked");
        const oTableLocked_head = dTableArea.find("table#oTable"+groupid+"_head_locked");
        if(oTable.length !== 1 || oTableLocked.length !== 1)
            return;
        oTableLocked.find("tr[data-rowkey]").each(function(){
            const rowKey = jQuery(this).attr("data-rowkey");
            const lockedRow = oTableLocked.find("tr[data-rowkey="+rowKey+"]");
            const dataRow = oTable.find("tr[data-rowkey="+rowKey+"]");
            if(lockedRow.length === 1 && dataRow.length === 1){
                const maxHeight = dataRow.height() >= lockedRow.height() ? dataRow.height() : lockedRow.height();
                lockedRow.add(dataRow).css("height", maxHeight);
                oTable_head.add(oTableLocked_head).find("tr[data-rowkey="+rowKey+"]").css("height", maxHeight);
            }
        });
        //解决隐藏列宽度变化问题,将数据层的隐藏列宽度总和赋值给锁定层
        const lockedCount = oTableLocked.find(".detailControlWidth").children().length;
        let totalWidth = 0;
        oTable.find(".detailControlWidth").children().each(function(index){
            if(index < lockedCount && !jQuery(this).hasClass("detail_hide_col"))
                totalWidth += jQuery(this).width();
        });
        if(Math.abs(oTableLocked.width()-totalWidth) > 3){
            dTableArea.find("table#oTable"+groupid+"_head_locked").width(totalWidth);
            oTableLocked.width(totalWidth);
        }
    }
    const begintime = new Date().getTime();
    const didsynctimer = window.setInterval(()=>{
        try{
            syncFn();
            const curtime = new Date().getTime(); 
            if(curtime - begintime > 2000)
                window.clearInterval(didsynctimer);
        }catch(e){}
    }, 200);
}

//锁定列情况，字段值变化后，同步行高度
const detailSyncRowController = {};
export const syncLockedRowHeight = (fieldid, rowIndex) =>{
    const { fieldAttrMap } = src.layoutStore;
    if(rowIndex < 0 || !fieldAttrMap.has(fieldid))
        return;
    const fieldAttr = fieldAttrMap.get(fieldid);
    const { tableMark,htmltype,detailtype } = fieldAttr;
    if(tableMark.indexOf("detail_") === -1 || (htmltype === 1 && detailtype > 1) || htmltype === 4)
        return;
    const groupid = parseInt(tableMark.substring(7)) - 1;
    const fieldMark = `field${fieldid}_${rowIndex}`;
    const dTableArea = jQuery("div#dTableArea_"+groupid);
    const fieldDom = dTableArea && dTableArea.find("[data-fieldmark="+fieldMark+"]");
    if(fieldDom.length === 0)
        return;
    const editTrDom = fieldDom.closest("tr");
    const rowKey = editTrDom.attr("data-rowkey");
    const rowDefHeight = fieldDom.closest("tr").attr("data-rowheight");
    if(!!rowKey && !!rowDefHeight){     //存在锁定列
        const lockedRow = dTableArea.find(".excelDetailContent_locked").find("tr[data-rowkey="+rowKey+"]");
        const dataRow = dTableArea.find(".excelDetailContent").find("tr[data-rowkey="+rowKey+"]");
        if(lockedRow.length === 1 && dataRow.length === 1){
            const rowDom = lockedRow.add(dataRow);
            const maxHeight = dataRow.height() >= lockedRow.height() ? dataRow.height() : lockedRow.height();
            rowDom.css("height", maxHeight);
            //定时同步一次，实现高度递减等情况的同步,每200ms执行一次，至多3s取消定时，控制每行同一时刻仅存在一个定时器
            const detailRowKey = `${tableMark}_${rowKey}`;
            if(!detailSyncRowController[detailRowKey]){
                const begintime = new Date().getTime();
                const synctimer = window.setInterval(()=>{
                    detailSyncRowController[detailRowKey] = "1";
                    const clearsynctimer = () =>{
                        window.clearInterval(synctimer);
                        detailSyncRowController[detailRowKey] = "";
                    }
                    let maxChildHeight = 0;
                    rowDom.children().each(function(){
                        const childHeight = jQuery(this).children(":first") && jQuery(this).children(":first").height() || 0;
                        if(childHeight > maxChildHeight)
                            maxChildHeight = childHeight;
                    });
                    if(Math.abs(maxHeight-maxChildHeight) > 4){
                        rowDom.css("height", maxChildHeight+4);
                        clearsynctimer();
                    }
                    const curtime = new Date().getTime(); 
                    if(curtime - begintime > 3000)
                        clearsynctimer();
                }, 200);
            }
        }
    }
}

//控制明细表位置，定位到表头滚动即将固定的状态
export const controlDetailPosition = (groupid) =>{
    const container = src.isMobile ? jQuery('.wf-req-content') : jQuery('.wf-req-form-scroll');
    const oTable = jQuery("#oTable"+groupid);
    const offset = oTable.offset().top;
    const scrollTop = container.scrollTop();
    const setOffsetTop = container.offset().top + 10;
    const setScrollTop = offset + scrollTop - setOffsetTop;
    if(setScrollTop > 0)
        container.scrollTop(setScrollTop);
}

/**
     * 判断是否将首行移到顶部，解决添加删除按钮跟着滚动问题
     * 需满足条件：
     * 1、开启横向滚动条、高级定制模式
     * 2、根据配置文件控制，默认开启
     * 3、首行包括添加删除按钮，且添加删除按钮不在锁定部分，且首行单元格不能包含除添加按钮、文字外其它类型，且首行单元格不能存在行合并
     */
export const judgeLockedBtnRow = (allowXScroll, detailLayout) =>{
    const { propFileCfg } = src.layoutStore;
    const { seniorset="0", edtitleinrow, edlockedcol="", ec} = detailLayout;
    const lockedCol = src.isMobile || isNaN(parseInt(edlockedcol)) ? -1 : parseInt(edlockedcol);
    if(!allowXScroll || propFileCfg.detail_locked_button_row !== "1" || parseInt(edtitleinrow) <= 1 || parseInt(seniorset) !== 1)
        return false;
    let hasButton = false;
    let disabledLocked = false;   
    ec.forEach(cell =>{
        const { id,rowspan="1",etype="1" } = cell;
        const rowid = parseInt(id.split(",")[0]);
        const colid = parseInt(id.split(",")[1]);
        if(rowid === 0){
            if(etype === "10" && colid > lockedCol)
                hasButton = true;
            if(etype === "" || etype === "0" || etype === "1" || etype === "10"){
                if(parseInt(rowspan) > 1)
                    disabledLocked = true;
            }else{
                disabledLocked = true;
            }
        }
    });
    return hasButton && !disabledLocked;
}

//计算指定区域下明细表样式，兼容标签页内嵌明细情况
export const calculateDetailAreaStyle = (area=jQuery()) =>{
    const { detailMap } = src.layoutStore;
    area.find(".wf-detail").each(function(){
        if(!jQuery(this).is(":visible"))
            return true;
        const excelDetailTableDiv = jQuery(this).find(".excelDetailTableDiv");
        const groupid = parseInt(excelDetailTableDiv.attr("data-groupid"));
        const swapWidth = excelDetailTableDiv.width();
        const dataAreaWidth = excelDetailTableDiv.find("#oTable"+groupid).width();
        const lockedAreaWidth = excelDetailTableDiv.find("#oTable"+groupid+"_locked") && excelDetailTableDiv.find("#oTable"+groupid+"_locked").width() || 0;
        const detailObj = detailMap.get("detail_"+(groupid+1));
        if(swapWidth >=dataAreaWidth ){     //宽度不足，横向滚动条失效
            detailObj.controlVariableMap("forceDisabledScrollX", true);
        }else if(swapWidth+(src.isMobile?-60:10) <= lockedAreaWidth){      //锁定宽度过大，锁定列失效
            window.WfForm.showMessage(src.getLabel(514714, "锁定列已超出明细$s可显示宽度，锁定列失效").replace("$s", groupid+1), 1, 4);
            detailObj.controlVariableMap("forceDisabledLocked", true);
        }
        const lockedBtnRow = jQuery(this).find(".wf-detail-locked-btnrow");
        if(lockedBtnRow.length > 0){
            const topRowHeight = lockedBtnRow.height();
            const topRowWidth = lockedBtnRow.parent().width();
            lockedBtnRow.find(".wf-detail-locked-btnrow-content").width(topRowWidth);
            lockedBtnRow.find(".wf-detail-locked-btnrow-placeholder").height(topRowHeight);
        }
        syncLockedForDidMount(groupid);
    });
}

//移动端滚动过程中，控制锁定列滑动提示的位置与显示
export const controlSlidePrompt = () =>{
    const container = jQuery('.wf-req-content');
    const baseTop = container.offset().top + container.height();
    const { detailMap } = src.layoutStore;
    jQuery('.wf-req-content').find(".excelDetailTableDiv").each(function(){
        if(jQuery(this).attr("data-supportlockedcol") !== "true")
            return true;
        const groupid = parseInt(jQuery(this).attr("data-groupid"));
        const lockedTable = jQuery(this).find("#oTable"+groupid+"_locked");
        const detailObj = detailMap.get(`detail_${groupid+1}`);
        const variableMap = detailObj.variableMap;
        if(lockedTable.length !== 1 || variableMap.has("slideprompt_show") || lockedTable.offset().top+30 > baseTop)
            return;
        //明细处于可视区域，滑动提示显示3s自动消失    
        const lastHeadRow = lockedTable.find("tr[data-rowKey^=headRow]").last();
        const top = lastHeadRow.offset().top+lastHeadRow.height()/2-lockedTable.offset().top;
        const left = lockedTable.width()-2;
        detailObj.batchControlVariableMap({slideprompt_show:true, slideprompt_top:top, slideprompt_left:left});
        window.setTimeout(()=>{
            detailObj.batchControlVariableMap({slideprompt_show:false});
        }, 2000)
    });
}